package vip.liux.front.infrastructure.config;

import io.micrometer.observation.ObservationRegistry;
import io.micrometer.observation.ObservationTextPublisher;
import io.micrometer.observation.aop.ObservedAspect;
import org.slf4j.Logger;
import org.springframework.boot.actuate.audit.AuditEventRepository;
import org.springframework.boot.actuate.audit.InMemoryAuditEventRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.AuditorAware;
import vip.liux.front.infrastructure.annotations.AuditedConfigurer;
import vip.liux.front.infrastructure.annotations.EnableAudited;
import vip.liux.front.infrastructure.aop.interceptor.IAuditingStore;
import vip.liux.front.infrastructure.security.CurrentUser;

import java.util.Objects;
import java.util.Optional;

@EnableAudited
@Configuration(proxyBeanMethods = false)
public class AuditConfiguration implements AuditedConfigurer {

    public final Logger logger = org.slf4j.LoggerFactory.getLogger(AuditConfiguration.class);

    @Bean
    AuditEventRepository auditEventRepository() {
        return new InMemoryAuditEventRepository();
    }

    @Override
    public IAuditingStore getAuditingStore() {
        return auditLog -> logger.info("AuditLogInfo: {}", auditLog);
    }

    @Bean
    public AuditorAware<String> setUserAuditorAware(CurrentUser currentUser) {
        return () -> Optional.ofNullable(currentUser.getId()).map(Objects::toString);
    }

    @Bean
    public ObservationTextPublisher observationTextPublisher() {
        return new ObservationTextPublisher(s -> logger.debug("ObservationTextPublisher: {}", s));
    }

    @Bean
    public ObservedAspect observedAspect(ObservationRegistry observationRegistry) {
        return new ObservedAspect(observationRegistry);
    }
}
